public class 字节码定义 {

    public static class 指令 {
        String 名称; // 例如： iadd, call
        int[] 操作数 = new int[3];
        int 操作数个数;

        public 指令(String 名称, int... 操作数) {
            this.名称 = 名称;

            if (操作数.length > 3) throw new IllegalArgumentException("最多支持3个操作数");
            System.arraycopy(操作数, 0, this.操作数, 0, 操作数.length);
            操作数个数 = 操作数.length;
        }
    }

    // 操作数类型
    public static final int 寄存器 = AssemblerParser.REG;
    public static final int 函数 = AssemblerParser.FUNC;
    public static final int 整数 = AssemblerParser.INT;
    public static final int 常量池索引 = 1000; // 魔数，只要确保它跟前面几个类型的值不同即可

    // 指令字节码（Java中没有无符号byte，因此使用short代替，由于只使用short的低字节，所以要确保取值在 [0,255] 范围内）
    public static final short 指令_IADD = 1;    // int add
    public static final short 指令_ISUB = 2;
    public static final short 指令_IMUL = 3;
    public static final short 指令_ILT = 4;     // int less than
    public static final short 指令_IEQ = 5;     // int equal
    public static final short 指令_FADD = 6;    // float add
    public static final short 指令_FSUB = 7;
    public static final short 指令_FMUL = 8;
    public static final short 指令_FLT = 9;     // float less than
    public static final short 指令_FEQ = 10;
    public static final short 指令_ITOF = 11;   // int to float
    public static final short 指令_CALL = 12;
    public static final short 指令_RET = 13;    // return with/without value
    public static final short 指令_BR = 14;     // branch
    public static final short 指令_BRT = 15;    // branch if true
    public static final short 指令_BRF = 16;    // branch if false
    public static final short 指令_CCONST = 17;  // load constant char
    public static final short 指令_ICONST = 18;  // load constant integer
    public static final short 指令_FCONST = 19;  // load constant float
    public static final short 指令_SCONST = 20;  // load constant string
    public static final short 指令_GLOAD = 21;   // load from global memory
    public static final short 指令_GSTORE = 22;  // store in global memory
    public static final short 指令_FLOAD = 23;   // field load
    public static final short 指令_FSTORE = 24;  // store field
    public static final short 指令_MOVE = 25;   // reg to reg move
    public static final short 指令_PRINT = 26;   // print reg
    public static final short 指令_STRUCT = 27; // create new struct
    public static final short 指令_NULL = 28;   // load null into register
    public static final short 指令_HALT = 29;


    public static final 指令[] 指令集 = new 指令[]{ // 数组下标代表指令字节码（操作码）
            null, // <无效指令>
            new 指令("iadd", 寄存器, 寄存器, 寄存器),
            new 指令("isub", 寄存器, 寄存器, 寄存器),
            new 指令("imul", 寄存器, 寄存器, 寄存器),
            new 指令("ilt", 寄存器, 寄存器, 寄存器),
            new 指令("ieq", 寄存器, 寄存器, 寄存器),
            new 指令("fadd", 寄存器, 寄存器, 寄存器),
            new 指令("fsub", 寄存器, 寄存器, 寄存器),
            new 指令("fmul", 寄存器, 寄存器, 寄存器),
            new 指令("flt", 寄存器, 寄存器, 寄存器),
            new 指令("feq", 寄存器, 寄存器, 寄存器),
            new 指令("itof", 寄存器, 寄存器),
            new 指令("call", 函数, 寄存器),
            new 指令("ret"),
            new 指令("br", 整数),
            new 指令("brt", 寄存器, 整数),
            new 指令("brf", 寄存器, 整数),
            new 指令("cconst", 寄存器, 整数),
            new 指令("iconst", 寄存器, 整数),
            new 指令("fconst", 寄存器, 常量池索引),
            new 指令("sconst", 寄存器, 常量池索引),
            new 指令("gload", 寄存器, 整数),
            new 指令("gstore", 寄存器, 整数),
            new 指令("fload", 寄存器, 寄存器, 整数),
            new 指令("fstore", 寄存器, 寄存器, 整数),
            new 指令("move", 寄存器, 寄存器),
            new 指令("print", 寄存器),
            new 指令("struct", 寄存器, 整数),
            new 指令("null", 寄存器),
            new 指令("halt")
    };
}
